import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author @fiber-cloud
 * @Date 2025/10/9 10:38
 * TCP回显服务器的服务端
 */
public class TcpEchoServer {
    private ServerSocket serverSocket = null;

    public TcpEchoServer(int port) throws IOException{
        serverSocket = new ServerSocket(port);
    }

    public void start() throws  IOException{
        System.out.println("启动服务器");
        // 此处使用 CachedThreadPool, 使用 FixedThreadPool 不太合适 (线程数不太应该是有固定的....)
        ExecutorService threadPool = Executors.newCachedThreadPool();

        while (true){
            Socket clientSocket = serverSocket.accept();
            threadPool.submit(()->{
                processConnection(clientSocket);
            });
        }

//        //使用多线程处理
//        Thread thread = new Thread(()->{
//            processConnection(clientSocket);}
//        );
//        thread.start();
        //使用线程池




//        while (true){
//            // 使用这个 clientSocket 和具体的客户端进行交流.
//            Socket clientSocket = serverSocket.accept();
//            processConnection(clientSocket);
//        }
    }

    //处理链接
    // 这个链接对应到一个客户端，可能会涉及到多次交互
    private void processConnection(Socket clientSocket) {
        System.out.printf("[%s:%d] 客户端上线！\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
        //基于socket对象和客户端进行通信
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()){


            //处理请求与响应

            while (true){
                // 1.读取请求
                Scanner scanner = new Scanner(inputStream);
                if (!scanner.hasNext()){
                    //没有下一个数据 —— 客户端关闭了连接
                    System.out.printf("[%s:%d] 客户端下线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
                    break;
                }
                //next——一直读取到换行符/空格/其他空白符结束，但返回结果中不包含上述空白符
                String request = scanner.next();
                // 2.根据请求构造响应
                String response = process(request);
                // 3.返回响应结果
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(request);
                //刷新缓冲区，保证写入的数据确实是发送出去了。
                printWriter.flush();


                System.out.printf("[%s:%d] req: %s; resp: %s \n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),
                        request,response);
            }

        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                clientSocket.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }


    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(9090);
        server.start();
    }
}
